package com.bootdo.lgs.order.service.impl;

import com.bootdo.common.excelread.service.ExcelRead;
import com.bootdo.common.excelread.service.model.ColumnFieldMapper;
import com.bootdo.common.exception.ParmException;
import com.bootdo.common.sms.model.SmsType;
import com.bootdo.common.sms.service.AliSms;
import com.bootdo.common.utils.AnnoExportExcel;
import com.bootdo.lgs.combox.dao.ComboxMapper;
import com.bootdo.lgs.combox.model.Combox;
import com.bootdo.lgs.lgsInterfaces.blc.service.BlcService;
import com.bootdo.lgs.lgsInterfaces.jzy.JzyLogisticsService;
import com.bootdo.lgs.order.dao.OrderMapper;
import com.bootdo.lgs.order.model.LgsNotice;
import com.bootdo.lgs.order.model.LgsOrder;
import com.bootdo.lgs.order.model.LgsOrderQuery;
import com.bootdo.lgs.order.model.OrderExcel;
import com.bootdo.lgs.order.service.OrderService;
import com.bootdo.lgs.orderbind.model.OrderBindUpdate;
import com.bootdo.lgs.orderbind.service.OrderBindService;
import com.bootdo.oa.domain.NotifyDO;
import com.bootdo.oa.service.NotifyService;
import com.bootdo.system.domain.UserDO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.bootdo.common.utils.ShiroUtils.getUser;


@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    ComboxMapper comboxMapper;

    @Autowired
    private ExcelRead excelRead;

    @Autowired
    private AliSms aliSms;

    @Resource
    private NotifyService notifyService;

    @Autowired
    OrderBindService orderBindService;

    @Autowired
    BlcService blcService;

    @Override
    public List getList(LgsOrderQuery condition) {
        if (condition.getQ_track_number() != null && !"".equals(condition.getQ_track_number())) {
            condition.setQ_track_number(condition.getQ_track_number().trim());
            if ((condition.getQ_track_number().startsWith("e") || condition.getQ_track_number().startsWith("E"))) {
                condition.setXd_track_number(condition.getQ_track_number());
            } else {
                condition.setLgs_track_number(condition.getQ_track_number());
            }
        }
        return orderMapper.getList(condition);
    }

    @Override
    public boolean add(LgsOrder condition, UserDO loginUser) {
        condition.setRecord_user_id(loginUser.getUserId());
        condition.setRecord_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderMapper.add(condition) > 0;
    }

    @Override
    public boolean insertBatchByExcel(OrderExcel condition, UserDO loginUser) throws Exception {
        ColumnFieldMapper columnFieldMapper = new ColumnFieldMapper();
        columnFieldMapper.addMap("物流公司", "").addMap("货物名称", "")
                .addMap("运输方式", "").addMap("发货件数", "")
                .addMap("客户名称", "").addMap("合同编号", "")
                .addMap("价值声明", "")
                .addMap("收货人", "").addMap("交付方式", "")
                .addMap("收货人电话", "").addMap("产品尺寸", "")
                .addMap("收获地址", "").addMap("备注", "")
                .addMap("发货人", "").addMap("发货人电话", "")
                .addMap("发货地址", "");
        List<ArrayList<String>> excelList = excelRead.readExcel(condition.getFile(), columnFieldMapper, false);
        if (excelList == null || excelList.size() < 1)
            throw new ParmException("excel表数据为空");
        List addList = new ArrayList();
        List companys = comboxMapper.getComboxByGrpCd("LGS_COMPANY");
        List transports = comboxMapper.getComboxByGrpCd("TRANSPORT_MODE");
        List deliverys = comboxMapper.getComboxByGrpCd("DELIVERY_METHOD");
        String dateNow = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        excelList.forEach(item -> {
            LgsOrder obj = new LgsOrder();
            obj.setLgs_company_nm(item.get(0)); //物流公司
            obj.setLgs_company_cd(getCodeByName(item.get(0), companys));//根据物流公司名称获取code
            obj.setGoods_name(item.get(1)); //货物名称
            obj.setTransport_mode_nm(item.get(2)); //运输方式
            obj.setTransport_mode_cd(getCodeByName(item.get(2), transports));//根据运输方式名称获取code
            obj.setDelivery_qty(item.get(3)); //发货件数
            obj.setCustomer_name(item.get(4)); //客户名称
            obj.setContract_number(item.get(5)); //合同编号
            obj.setValue_statement(item.get(6)); //价值声明
            obj.setConsignee(item.get(7)); //收货人
            obj.setDelivery_method_nm(item.get(8)); //交付方式
            obj.setDelivery_method_cd(getCodeByName(item.get(8), deliverys));//根据交付方式名称获取code
            obj.setConsignee_phone(item.get(9)); //收货人电话
            obj.setProduct_size(item.get(10)); //产品尺寸
            obj.setConsignee_address(item.get(11)); //收获地址
            obj.setRemark(item.get(12)); //备注
            obj.setSender(item.get(13)); //发货人
            obj.setSender_phone(item.get(14)); //发货人电话
            obj.setSender_address(item.get(15)); //发获地址

            obj.setRecord_user_id(loginUser.getUserId());
            obj.setRecord_date(dateNow);
            addList.add(obj);
        });
        condition.setAddList(addList);
        orderMapper.insertBatch(condition);
        return true;
    }

    private String getCodeByName(String name, List<Combox> list) {
        if (list == null || list.isEmpty() || name == null || "".equals(name))
            return "";
        for (Combox combox : list) {
            if (combox.getName().equals(name))
                return combox.getValue();
        }
//		Combox combox = null;
//		try {
//			combox = list.stream().filter(item->item.getName().equals(name)).findAny().get();
//		} catch (Exception e) {
//			e.printStackTrace();
//			return "";
//		}
        //没找到返回空
        return "";
    }

    @Override
    public LgsOrder getDataById(Long id) {
        return orderMapper.getDataById(id);
    }

    @Override
    public List<LgsOrder> batchQuery(Long[] ids) {
        return orderMapper.getLgsOrdersByIds(Arrays.asList(ids));
    }

    @Override
    public boolean update(LgsOrder condition, UserDO loginUser) {
        if (loginUser != null && loginUser.getUserId() != null)
            condition.setUpdate_user_id(loginUser.getUserId());
        condition.setUpdate_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderMapper.update(condition) > 0;
    }

    @Override
    public boolean addComment(LgsOrder condition) {
        condition.setUpdate_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderMapper.addComment(condition) > 0;
    }

    @Override
    public boolean delete(Long id) {
        orderMapper.delete(id);
        return true;
    }

    @Override
    public boolean batchUpdate(List<LgsOrder> list, UserDO loginUser) {
        if(CollectionUtils.isEmpty(list))
            throw new ParmException("下单 订单为空");
        //通过ids查询订单，主要查询出订单状态，防止重复下单
        List<Long> ids = list.stream().map(LgsOrder::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ids))
            list = orderMapper.getLgsOrdersByIds(ids);
        List<LgsOrder> batchUpdateList = new ArrayList<>();
        //先查询出来当天的雄帝单号个数
        //循环list生成 雄帝订单号、同时设置lgs_status=2 生成雄帝运单号 EYYMMDDnnn
        String nowStr = new SimpleDateFormat("yyMMdd").format(new Date());
        Long num = new Date().getTime();
        int maxInt = getLast3ByDateStr(nowStr);
        int cnt = 1;
        for (int i = 0; i < list.size(); i++) {
            //已经存在雄帝运单号，使用原来的雄帝订单号，不存在时生成雄帝运单号
            if (list.get(i).getXd_track_number() == null || "".equals(list.get(i).getXd_track_number().trim())) {
                String xdTnum = getXdTnum(nowStr, maxInt, cnt);
                list.get(i).setXd_track_number(xdTnum);//雄帝运单号生成方案 EYYMMDDnnn
                cnt++;
            }
            if ("1".equals(list.get(i).getLgs_status())) {//只能对1未下单状态订单下单
                list.get(i).setLgs_status("3");
                list.get(i).setOrder_user_id(loginUser.getUserId());
                list.get(i).setOrder_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                batchUpdateList.add(list.get(i));
            }
        }
        if (batchUpdateList.size() > 0) {
            System.out.println("下单运单："+batchUpdateList);
            if (orderMapper.batchUpdate(batchUpdateList) > 0) {
                sendOrders(batchUpdateList);//下单给相应物流公司系统
                sendMsg(batchUpdateList);//发送短信 提醒
            }
        }
        return true;
    }

    private void sendOrders(List<LgsOrder> orderList) {
        List<Long> ids = orderList.stream().map(LgsOrder::getId).collect(Collectors.toList());
        List orders = orderMapper.getLgsOrdersByIds(ids);//根据id查询出 订单信息
        List<OrderBindUpdate> condition = sendOrderToLgsCompany(orders);
        if (condition != null && condition.size() > 0) //绑定单号
            orderBindService.batchUpdateLgsNumber(condition, getUser());
    }

    private List<OrderBindUpdate> sendOrderToLgsCompany(List<LgsOrder> orders){
        List<OrderBindUpdate> result = new ArrayList<>();

        Map<String,List<LgsOrder>> map = orders.stream().collect(Collectors.groupingBy(LgsOrder::getLgs_company_cd));
        for (Map.Entry<String, List<LgsOrder>> entry : map.entrySet()) {
            if("lgs_jcy".equals( entry.getKey())){ //下发今朝阳
                List<LgsOrder> list =   entry.getValue();
                try {
                    result.addAll(JzyLogisticsService.saveOrders(list));
                } catch (Exception e) {
                    logger.warn("下单给今朝阳物流系统失败。"+list,e);
                }
            }else if( "lgs_blc".equals(entry.getKey()) ){ //下发百路驰
                List<LgsOrder> list =   entry.getValue();
                result.addAll(blcService.sendOrders(list));
            }
        }
        return result;
    }

    //发送短信 提醒
    private void sendMsg(List<LgsOrder> batchUpdateList) {
        try {
            List<LgsNotice> lgsNotices = orderMapper.getLgsNotices(batchUpdateList);
            if (lgsNotices != null && !lgsNotices.isEmpty()) {
                for (LgsNotice lgsNotice : lgsNotices) {
                    aliSms.send(lgsNotice.getPhone(), "", SmsType.XD_ORDER_CREATE, "{\"xd_order_id\":\"" +
                            lgsNotice.getXd_order_ids() +
                            "\"}");
                }
            }
        } catch (Exception e) {
            logger.warn("短信发送失败。" + batchUpdateList);
        }
    }

    //雄帝运单号生成方案 EYYMMDDnnn
    private String getXdTnum(String dateStr, int maxInt, int cnt) {
        return "E" + dateStr + (get3NStr(maxInt, cnt));
    }

    //编号+cnt后，返回补0的三位字符串nnn数字，
    private String get3NStr(int maxInt, int cnt) {
        int startNum = maxInt;
        int resultNum = startNum + cnt;
        if (resultNum > 999)
            System.out.println("抛出异常，当天的运单数超过最大数量999限制，请联系管理员调整运单号策略");
        return String.format("%03d", resultNum);
    }

    //获取当天雄帝运单号 最大的单号、取出最后三位字符串nnn、
    //转换为整数返回
    private int getLast3ByDateStr(String dateStr) {
        String nnn = orderMapper.getLast3ByDateStr("E" + dateStr);//通过数据库查询出来,查询出错报异常
        if (nnn == null || "".equals(nnn.trim()))
            return 0;
        return Integer.parseInt(nnn);
    }

    @Override
    public void export(LgsOrderQuery condition, HttpServletResponse response) {
        try {
            new AnnoExportExcel("对账单", LgsOrder.class, 2).setDataList(orderMapper.getExportList(condition)).write(response);
        } catch (IOException e) {
            e.printStackTrace();
            //log.warn("调度令管理列表-导出excel失败，condition:"+condition,response);
        }
    }

    @Override
    public List getComboxByGrpCd() {
        return comboxMapper.getComboxByGrpCd("LGS_COMPANY");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateAfterDeliver(LgsOrder condition, UserDO loginUser) {
        LgsOrder original = this.getDataById(condition.getId());
        String info = "";
        if (!original.getCustomer_name().equals(condition.getCustomer_name())) {
            info += "</br>原收货客户：" + original.getCustomer_name() + " 修改后：" + condition.getCustomer_name();
        }
        if (!original.getConsignee().equals(condition.getConsignee())) {
            info += "</br>原收货人：" + original.getConsignee() + " 修改后：" + condition.getConsignee();
        }
        if (!original.getConsignee_phone().equals(condition.getConsignee_phone())) {
            info += "</br>原收货电话：" + original.getConsignee_phone() + " 修改后：" + condition.getConsignee_phone();
        }
        if (!original.getConsignee_address().equals(condition.getConsignee_address())) {
            info += "</br>原收货地址：" + original.getConsignee_address() + " 修改后：" + condition.getConsignee_address();
        }

        if (StringUtils.isBlank(info)) {
            return false;
        }

        if (this.update(condition, loginUser)) {
            NotifyDO notifyDO = new NotifyDO();
            notifyDO.setType("4");
            notifyDO.setTitle("【物流订单信息变更提醒】");
            notifyDO.setContent("系统检测到运单号【" + original.getLgs_track_number() + "】在已收货状态下变更物流订单信息" + info);
            notifyService.notifyOrderTrace(original.getId(), original.getLgs_company_cd(), notifyDO);
            return orderMapper.addHisRecord(original) > 0;
        }

        return false;
    }
}
